import configparser
import logging
from Login import *
import Sql
import sqlite3
import subprocess

##############
#author:张子路#
##############

class MyCnfigParser(configparser.ConfigParser):

    def optionxform(self, optionstr):
        return optionstr                       #重写类，使写入时不小写输出


class Reinforce():     #完成配置项加固
    def __init__(self):
        try:
            self.Sql=Sql.SqlInformation()
        except Exception as e:
            logging.error("连接文件Sql.py失败 {0}".format(e), exc_info=True)
        try:
            self.conn = sqlite3.connect("./DEMO.db")
            self.cur = self.conn.cursor()
        except Exception as e:
            logging.error("数据库读取创建出错 {0}".format(e), exc_info=True)

    def __del__(self):
        self.conn.close()

    def Inport(self):
        cmd=r'secedit /configure /db temp.sdb /cfg setup.inf'
        try:
            res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)         #导入注册表
        except Exception as e:
            logging.error("执行命令失败 {0}".format(e), exc_info=True)

    def Start(self):
        date=[]
        try:
            self.HostConfig=MyCnfigParser(allow_no_value=True)
            self.HostConfig.read('./setup.inf',encoding='utf-16')     #连接导出的安全策略文件
        except Exception:
            print('配置文件读取错误。')
        if len(self.HostConfig.sections())==0:
            logging.error("配置文件读取错误，请检查文件位置。", exc_info=True)
        try:
            self.cur.execute('select * from StandrandConfigation')   #获取安全策略标准
        except Exception as e:
            logging.error("数据查询出错 {0},请先执行StandrandSql.py建立标准数据库。".format(e), exc_info=True)
        try:
            for iteam in self.cur.fetchall():
                date.append(['安全策略核查',eval(iteam[1])[0] ,eval(iteam[1])[1] ,eval(iteam[2]),eval(iteam[3]),iteam[4]])
            SearchResult=self.Sql.InSert(date)            #获取安全策略查询结果
        except Exception as e:
            logging.error("数据查询出错 {0}".format(e), exc_info=True)
        try:
            for iteam in SearchResult:      #根据对比方法检查是否符合规范
                cor=True
                cprm=eval(iteam[7])
                cprv=eval(iteam[8])
                if iteam[6]==None:         #当没有设置相应的安全策略时
                    cor=False
                else:
                    for cpr in range(len(cprm)):      #遍历对比方法，对比当前值是否符合规范
                        if cprm[cpr]=='st':
                            if int(cprv[cpr])<int(iteam[6]):
                                cor=False
                        if cprm[cpr]=='bt':
                            if int(cprv[cpr])>int(iteam[6]):
                                cor=False
                        if cprm[cpr]=='equ':
                            if cprv[cpr]!=iteam[6]:
                                cor=False
                        if cprm[cpr]=='not equ':
                            if cprv[cpr]==iteam[6]:
                                cor=False
                        if cprm[cpr]=='set to':
                            cuser=iteam[6].split(',')
                            suser=cprv[cpr]
                            for user in cuser:
                                if user not in suser:
                                    cor=False
                            for user in suser:
                                if user not in cuser:
                                    cor=False
                if not cor:
                    self.HostConfig.set(eval(iteam[5])[0],eval(iteam[5])[1],iteam[9])   #不符合规范时重写安全策略项
                    self.HostConfig.write(open("./setup.inf","w",encoding='utf-16')) #以utf-16写入文件

        except Exception as e:
            logging.error("生成结果出错 {0}".format(e), exc_info=True)
        try:
            self.Inport()
        except Exception as e:
            logging.error("导入注册表出错 {0}".format(e), exc_info=True)


if __name__ == "__main__":
    login=LoginStart()
    login.start()    #执行该文件时调用生成登录界面
    '''g=Reinforce()
    g.Start()'''